openapi: 3.0.3
info:  
  title: "PSA Verification of Payee - version 1.0.8 - 20250324"
  version: "1.0.9"
  description: |
    Technical specification for the VoP Application Programming Interface
    
    DATA REQUESTS
    
    ************************
    FOR PSA VoP PARTICIPANTS
    ************************
    
    CHANGES SINCE 1.0.8
    
    Correct BICType pattern to comply with ISO\
    Add data type vopLimitCode to allow limitation of response codes when responding on behalf of PSA participant\
    Insert vopLimit within verificationData for use of vopLimitCode

    CHANGES SINCE 1.0.7
    
    Add http 421 error possibility and description\
    Rework enum of messageCode to reflect possibilities and description\
    Rework position of errors and connected examples
    
  contact:
    name: 'PSA Payment Services Austria'
    url: 'https://www.psa.at/'
    email: 'office@psa.at'
    x-team-info:
      department: 'Account Systems'
      colleagues: 'Alexandra Karrer, Hendrik Muus, Marinko Ostojić'
externalDocs:
  description: |
    Verification of Payee PSA API description based on
    
    Verification Of Payee Scheme Rulebook - EPC218-23
    
    Verification Of Payee Inter-PSP API Specification - EPC103-24
    
    EPC API Security Framework - EPC164-22
    
  url: 'https://www.europeanpaymentscouncil.eu/what-we-do/other-schemes/verification-payee'
servers:
- url: https://api.endpoint.as.specified.by.member
  description: For requests from PSA to PSA VoP member that choose this work flow
paths:
  /payee-data:
    description: |
      Request of PSA VoP service to a financial institution being member that hasn't provided data to PSA, but using the matching facilities
      
      This request is called by PSA VoP service and response has to be provided by the financial institution being member that hasn't provided data to PSA, but using the matching facilities
      
    post:
      operationId: postVerificationOfPayeeDataRequest
      parameters:
      - $ref: '#/components/parameters/requestResponseId'
      - $ref: '#/components/parameters/requestTimestamp'
      - $ref: '#/components/parameters/originalRequestId'
      - $ref: '#/components/parameters/originalRequestTimestamp'
      - $ref: '#/components/parameters/originalRequesterBIC'
      requestBody:
        $ref: '#/components/requestBodies/dataRequest'
      responses:
        '200':
          $ref: '#/components/responses/dataPostResponse'
        '400':
          $ref: '#/components/responses/errors'
        '401':
          $ref: '#/components/responses/errors'
        '403':
          $ref: '#/components/responses/errors'
        '404':
          $ref: '#/components/responses/errors'
        '409':
          $ref: '#/components/responses/errors'
        '421':
          $ref: '#/components/responses/errors'
        '500':
          $ref: '#/components/responses/errors'
components:
  headers:
    originalRequestId:
      description: |
        The original's VoP Request Message reference number
      schema:
        $ref: '#/components/schemas/UUIDType'
    originalRequesterBIC:
      description: |
        The original's VoP Request Message requester's BIC
      schema:
        $ref: '#/components/schemas/BICType'
    originalRequestTimestamp:
      description: |
        The original's VoP Request Message timestamp
      schema:
        $ref: '#/components/schemas/dateTimeType'
    requestResponseId:
      description: |
        The Requester's reference number of the VoP Request Message
      required: true
      schema:
        $ref: '#/components/schemas/UUIDType'
    responseTimestamp:
      description: |
        The Requester's timestamp of the VoP Request Message
      schema:
        $ref: '#/components/schemas/dateTimeType'
      required: true
  parameters:
    originalRequestId:
      description: |
        The Requester's reference number of the VoP Request Message forwarded by the RVM (Routing and/or Verification Mechanism)
      in: header
      required: true
      name: X-Original-Request-Id
      schema:
        $ref: '#/components/schemas/UUIDType'
    originalRequesterBIC:
      description: |
        The Requester's BIC of the VoP Request Message forwarded by the RVM (Routing and/or Verification Mechanism)
      in: header
      required: true
      name: X-Original-Requesters-BIC
      schema:
        $ref: '#/components/schemas/BICType'
    originalRequestTimestamp:
      description: |
        The Requester's timestamp of the VoP Request Message forwarded by the RVM (Routing and/or Verification Mechanism)
      in: header
      required: true
      name: X-Original-Request-Timestamp
      schema:
        $ref: '#/components/schemas/dateTimeType'
    requestResponseId:
      description: |
        The Requester's reference number of the VoP Request Message
      in: header
      required: true
      name: X-Request-ID
      schema:
        $ref: '#/components/schemas/UUIDType'
    requestTimestamp:
      description: |
        The Requester's timestamp of the VoP Request Message
      in: header
      required: true
      name: X-Request-Timestamp
      schema:
        $ref: '#/components/schemas/dateTimeType'
  requestBodies:
    dataRequest:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/verificationOfPayeeDataRequest'
      required: true
  responses:
    dataPostResponse:
      description: |
        Data assigned by the Responder to be used for VoP processing by the RVM (Routing and/or Verification Mechanism)
      headers:
        X-Request-ID:
          $ref: '#/components/headers/requestResponseId'
        X-Response-Timestamp:
          $ref: '#/components/headers/responseTimestamp'
      content:
        application/json:
           schema:
            $ref: '#/components/schemas/verificationOfPayeeDataResponse'
    errors:
      description: |
        Error according descriptive content. May occur from outside application too.\
      headers:
        X-Request-ID:
          $ref: '#/components/headers/requestResponseId'
        X-Response-Timestamp:
          $ref: '#/components/headers/responseTimestamp'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/verificationOfPayeeError'
          examples:
            400:
              description: |
                Bad Request - malformed payload.
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400"
                code: "FORMAT_ERROR"
                title: "Malformed JSON"
                status: 400
                detail: "Request Body could not be parsed or otherwise recognised"
                instance: 
            400_b:
              description: |
                Bad Request - malformed payload.
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400"
                code: "TIMESTAMP_INVALID"
                title: "Timestamp not accepted"
                status: 400
                detail: "Diviation between timestamp and current time is out of accepted bounds"
                instance: 
            400_c:
              description: |
                Bad Request - malformed payload.
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400"
                code: "UNKNOWN_ERROR"
                title: "Unspecific error condition"
                status: 400
                detail: "Request Body could not be parsed or otherwise recognised"
                instance: 
            401:
              description: |
                Unauthorized - not correctly authenticated to perform the request, e.g. no certificate, not accepted certificate type, etc.\
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401"
                code: "CLIENT_INVALID"
                title: "Authorisation failed"
                status: 401
                detail: "No certificate or unfitting certificate type used"
                instance: 
            403:
              description: |
                Forbidden - authorisation issue, certificate not acceptable, e.g. certificate's NAN do not match BIC in request, etc.\

              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403"
                code: "CLIENT_INCONSISTENT"
                title: "NAN and BIC don't match"
                status: 403
                detail: "BIC derived from NAN of certificate doesn't match BIC in request"
                instance: 
            404:
              description: |
                Not Found - resource not existing, e.g. resource according path in request not existing.\
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404"
                code: "NOT_FOUND"
                title: "Cannot find the requested resource"
                status: 404
                detail: "Resource is missing or has never existed"
                instance: 
            409:
              description: |
                Conflict - header carry duplicate entry, i.e. request id already used.\
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409"
                code: "DUPLICATE"
                title: "RequestId already in use"
                status: 409
                detail: "The request identification is already in use and therefore cannot be accepted"
                instance: 
            421:
              description: |
                Misdirected Request - request was directed to wrong server, i.e. none of the BICs is service member.\
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/421"
                code: "MISDIRECTED_REQUEST"
                title: "Cannot provide information requested"
                status: 421
                detail: "Requester responder combination unsupported"
                instance: 
            422:
              description: |
                Unprocessable Content - content of request not fitting process requirements, e.g. inconsistent, contradicting or ambiguous.\
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422"
                code: "RESOURCE_NOT_FOUND"
                title: "Resource according Id not found"
                status: 422
                detail: "Transmitted resource Id not fount among available resource Ids"
                instance: 
            451:
              description: |
                Unavailable For Legal Reasons - owner of NAN not supported, e.g. missing agreement may lead to GDPR issues.\
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451"
                code: "CLIENT_UNKNOWN"
                title: "NAN not registered"
                status: 451
                detail: "The NAN given in certificate is not listed in list of supported requester's NANs"
                instance: 
            500:
              description: |
                Internal Server Error - technical problem occurred in the application code or application server preventing request execution.
              value:
                type: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500"
                code: "SERVER_ERROR"
                title: "Internal error occurred while processing request"
                status: 500
                detail: "Server reported an error during computing. Technical personal has been informed about this issue"
                instance: 
  schemas:
    BICType: 
      description: |
        Business Identifier Code according ISO 9362. May identify financial institutions and other organisations.
      type: string
      pattern: '^[A-Z0-9]{4}[A-Z]{2}[A-Z0-9]{2}([A-Z0-9]{3})?$'
      example: 'ABCDBEBBFIM'
    IBANType: 
      description: |
        InternationalBankAccountNumber according ISO 13616, as assigned by the responding PSP.
      type: string
      pattern: '^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$'
      example: 'AB121234567812345678901234'
    LEIType: 
      description: |
        Code LEI (Legal Entity Identifier) according ISO 17442.
      type: string
      pattern: '^[A-Z0-9]{18}[0-9]{2}$'
      example: '549300DTUYXVMJXZNY75'
    UUIDType:
      description: | 
        A UUID according RFC 4122 Version 4.
      type: string
      format: uuid
      pattern: '^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$'
      example: '9f45a3e5-aa49-43d6-9f1c-36ae3b5a295e'
    academicTitleType:
      description: | 
        Acquired academic title and title position relative to name
      type: object
      properties:
        title:
          $ref: '#/components/schemas/max35Text'
        position:
          enum: [before, after]
      required:
        - title
        - position
    accountType:
      description: |
        InternationalBankAccountNumber according ISO 13616, as assigned by the responding PSP.
      type: object
      properties:
        iban:
          $ref: '#/components/schemas/IBANType' 
      required:
        - iban
    addressType:
      description: | 
        Address information
      type: object
      properties:
        department:
          $ref: '#/components/schemas/max70Text'
        subDepartment:
          $ref: '#/components/schemas/max70Text'
        streetName:
          $ref: '#/components/schemas/max70Text'
        buildingNumber:
          $ref: '#/components/schemas/max16Text'
        buildingName:
          $ref: '#/components/schemas/max35Text'
        floor:
          $ref: '#/components/schemas/max70Text'
        postBox:
          $ref: '#/components/schemas/max16Text'
        room:
          $ref: '#/components/schemas/max70Text'
        postCode:
          $ref: '#/components/schemas/max16Text'
        townName:
          $ref: '#/components/schemas/max35Text'
        townLocationName:
          $ref: '#/components/schemas/max35Text'
        districtName:
          $ref: '#/components/schemas/max35Text'
        countrySubDevision:
          $ref: '#/components/schemas/max35Text'
        country:
          $ref: '#/components/schemas/countryCode'
      required:
        - townName
        - country
    birthType:
      description: | 
        Information on person's birth
      type: object
      properties:
        birthDay:
          $ref: '#/components/schemas/dateType'
        provinceOfBirth:
          $ref: '#/components/schemas/max35Text'
        cityOfBirth:
          $ref: '#/components/schemas/max35Text'
        countryOfBirth:
          $ref: '#/components/schemas/countryCode'
      required:
       - birthDay
       - cityOfBirth
       - countryOfBirth
    countryCode:
      description: | 
        Two alpha country code according ISO 3166
      type: string
      pattern: '^[A-Z]{2}$'
      example: 'AT'
    dateTimeType:
      description: |
        Timestamp in ISO 8601 format, either UTC (YYYY-MM-DDThh:mm:ss.sssZ) or local time with UTC offset (YYYY-MM-DDThh:mm:ss.sss+/-hh:mm), milliseconds precision (observe truncation rules !).
      type: string
      format: date-time
      pattern: '^\d{4}(-\d{2}){2}T\d{2}(:\d{2}){2}(\.\d{0,2}[1-9])?(Z|([-+]\d{2}(:\d{2})?))$'
      example: '2024-12-12T12:12:12Z ; 2024-12-12T12:12:12.02Z ; 2024-12-12T12:12:10+02'
    dateType:
      description: |
        Date in ISO 8601 format, either UTC (YYYY-MM-DDZ) or local time with UTC offset (YYYY-MM-DD+/-hh:mm).
      type: string
      format: date-time
      pattern: '^\d{4}(-\d{2}){2}(Z|([-+]\d{2}(:\d{2})?))$'
      example: '2024-12-12Z'
    genderType:
      description: |
        Gender of person from documents used in KYC process
      type: string
      enum: [Male, Female, Other]
      example: 'Other'
    genericOrganisationId:
      description: | 
        An organisation identifier and an identifier type qualified by either ‘schemeNameCode’ or ‘schemeNameProprietary’ and optionally an identifier issuer information
      oneOf:
        - $ref: '#/components/schemas/organisationCodedId'
        - $ref: '#/components/schemas/organisationProprietaryId'
    genericPersonId:
      description: | 
        A person identifier and an identifier type qualified by either ‘schemeNameCode’ or ‘schemeNameProprietary’ and optionally an identifier issuer information
      type: object
      properties:
        identification:
          $ref: '#/components/schemas/max35Text'
        schemeName:
          oneOf:
          - $ref: '#/components/schemas/schemeCode'
          - $ref: '#/components/schemas/proprietaryName'
        issuer:
          $ref: '#/components/schemas/max35Text'
      required:
        - identification
    idAsLEI:
      description: |
        Legal Entity Identifier according ISO 17442.
      type: object
      properties:
        lei:
          $ref: '#/components/schemas/LEIType'
    idAsBIC:
      description: |
        Business Identifier Code according ISO 9362. May identify financial institutions and other organisations.
      type: object
      properties:
        anyBIC:
          $ref: '#/components/schemas/BICType'
    idAsOther:
      description: | 
        An organisation identifier and an identifier type qualified by either ‘schemeNameCode’ or ‘schemeNameProprietary’ and optionally an identifier issuer information. Although the structure is an array, only one identifier is allowed
      type: object
      properties:
        others:
          type: array
          items:
            $ref: '#/components/schemas/genericOrganisationId'
          maxItems: 1
    idType:
      description: | 
        Unique identification of an organisation, as assigned by an institution, using an identification scheme.
      type: object
      properties:
        organisationId:
          $ref: '#/components/schemas/organisationIdType'
      required:
        - organisationId
    max140Text:
      type: string
      minLength: 1
      maxLength: 140
    max16Text:
      type: string
      minLength: 1
      maxLength: 16
    max256Text:
      type: string
      minLength: 1
      maxLength: 256
    max35Text:
      type: string
      minLength: 1
      maxLength: 35
    max500Text:
      type: string
      minLength: 1
      maxLength: 500
    max70Text:
      type: string
      minLength: 1
      maxLength: 70
    messageCode:
      description: | 
        Specifies the codes Error messages.
      type: string
      enum: [FORMAT_ERROR, TIMESTAMP_INVALID, UNKNOWN_ERROR, CLIENT_INVALID, CLIENT_INCONSISTENT, NOT_FOUND, DUPLICATE, MISDIRECTED_REQUEST, RESOURCE_NOT_FOUND, CLIENT_UNKNOWN, SERVER_ERROR]
      example: 'TIMESTAMP_INVALID'
    organisationCodedId:
      description: |
        Unique and unambiguous identification of an organisation according provided coded scheme within issuers space.
      type: object
      properties:
        identification:
          $ref: '#/components/schemas/max256Text'
        schemeNameCode:
          $ref: '#/components/schemas/organisationIdCode'
        issuer:
          $ref: '#/components/schemas/max35Text'
      required:
        - identification
        - schemeNameCode
    organisationIdCode:
      description: |
        Specifies the external organisation identification scheme name code (maximum 4 characters) as defined in an external list (iso20022.org).
      type: string
      enum: [BANK, CBID, CHID, CINC, COID, CUST, DUNS, EMPL, GS1G, SREN, SRET, TXID, BDID, BOID]
      example: 'BOID'
    organisationIdType:
      description: | 
        Unique identification of an organisation, as assigned by an institution, using an identification scheme.
      oneOf:
        - $ref: '#/components/schemas/idAsLEI'
        - $ref: '#/components/schemas/idAsBIC'
        - $ref: '#/components/schemas/idAsOther'
    organisationProprietaryId:
      description: |
        Unique and unambiguous identification of an organisation according provided proprietary scheme eventually within issuers space.
      type: object
      properties:
        identification:
          $ref: '#/components/schemas/max256Text'
        schemeNameProprietary:
          $ref: '#/components/schemas/max35Text'
        issuer:
          $ref: '#/components/schemas/max35Text'
      required:
        - identification
        - schemeNameProprietary
    organisationType:
      description: | 
        Structure to hold information about an organisation
      type: object
      properties:
        type:
          $ref: '#/components/schemas/max35Text'
        identification:
          $ref: '#/components/schemas/idType'
        names:
          type: array
          items:
            $ref: '#/components/schemas/max140Text'
        aliases:
          type: array
          items:
            $ref: '#/components/schemas/max140Text'
        address:
          $ref: '#/components/schemas/addressType'
      required:
        - organisationNames
    partyData:
      description: | 
        Structure holding information about a party / parties associated with an account.
      type: object
      properties:
        person:
          type: array
          items:
            $ref: '#/components/schemas/personType'
        organisation:
          type: array
          items:
            $ref: '#/components/schemas/organisationType'
    personType:
      description: | 
        Structure to hold information about a person
      type: object
      properties:
        additionalInformation:
          $ref: '#/components/schemas/titlesType'
        firstNames:
          type: array
          items:
            $ref: '#/components/schemas/max140Text'
        lastNames:
          type: array
          items:
            $ref: '#/components/schemas/max140Text'
        name:
          $ref: '#/components/schemas/max140Text'
        aliases:
          type: array
          items:
            $ref: '#/components/schemas/max140Text'
        address:
          $ref: '#/components/schemas/addressType'
        birthName:
          $ref: '#/components/schemas/max140Text'
        officialGender:
          $ref: '#/components/schemas/genderType'
        dateAndPlaceOfBirth:
          $ref: '#/components/schemas/birthType'
        identification:
          type: array
          items:
            $ref: '#/components/schemas/genericPersonId'
    proprietaryName:
      description: | 
        Proprietary information about the kind and/or nature of a code
      type: object
      properties:
        proprietary:
          $ref: '#/components/schemas/max35Text'
      required:
        - proprietary
    schemeCode:
      description: |
        Coded information about the kind and/or nature of a code
      type: object
      properties:
        code:
          $ref: '#/components/schemas/schemeType'
      required:
        - code
    schemeType:
      description: |
        Codes for the kind and/or nature of a code
      type: string
      enum: [ARNU, CCPT, CUST, DRLC, EMPL, NIDN, POID, SOSE, TELE, TXID]
      example: 'CCPT'
    titlesType:
      description: | 
        Structure for titles and other not categorised information connected to a person
      type: object
      properties:
        salutation:
          $ref: '#/components/schemas/max35Text'
        academicTitles:
          type: array
          items:
            $ref: '#/components/schemas/academicTitleType'
        otherTitles:
          type: array
          items:
            $ref: '#/components/schemas/max35Text'
        knownNames:
          type: array
          items:
            $ref: '#/components/schemas/max35Text'
    verificationData:
      description: | 
        Data returned to apply matching algorithms on.
      type: object
      properties:
        partyAccount:
          $ref: '#/components/schemas/accountType'
        vopLimit:
          $ref: '#/components/schemas/vopLimitCode'
        accountSince:
          $ref: '#/components/schemas/dateType'
        associatedNamesAndIds:
          $ref: '#/components/schemas/partyData'
      required:
        - partyAccount
        - associatedNamesAndIds
    verificationDataError:
      description: |
        No data returnable.
      type: object
      properties:
        partyMatch:
          description: | 
            In case no data can or shall be returned
          type: string
          enum: [NOAP]
          example: 'NOAP'
      required:
        - partyMatch
    verificationOfPayeeDataRequest:
      description: | 
        Request for the data needed for verification process.
      type: object
      properties:
        partyAccount: 
          $ref: '#/components/schemas/accountType'
      required:
        - partyAccount
    verificationOfPayeeDataResponse:
      description: | 
        Result of the verification data request.
      oneOf:
        - $ref: '#/components/schemas/verificationData'
        - $ref: '#/components/schemas/verificationDataError'
    verificationOfPayeeError:
      description: |
        Provides information on an error occurred.
      type: object
      properties:
        type: 
          $ref: '#/components/schemas/max70Text'
        code:
          $ref: '#/components/schemas/messageCode'
        title:
          $ref: '#/components/schemas/max70Text'
        status:
          type: integer
          enum: [400,401,403,404,409,421,422,451,500]
        detail:
          $ref: '#/components/schemas/max500Text'
        instance:
          $ref: '#/components/schemas/max256Text'
      required:
        - type
        - code
    vopLimitCode:
      description: | 
        Determines the range of VoP response codes that shall be used in responses
      type: string
      enum: [NOAP, MONA, NOCM, FULL]
      example: 'FULL'